//
//  CoGeThreadSafeMutableDictionary.m
//  CoGe
//
//  Created by Tamas Nagy on 4/30/11.
//  Copyright 2011 home. All rights reserved.
//

#import "CoGeThreadSafeMutableDictionary.h"


@implementation CoGeThreadSafeMutableDictionary

- (id) init;
{
    self = [super init];
    if (self != nil) {
        spinlock = OS_SPINLOCK_INIT;
        theDict = [[NSMutableDictionary alloc] init]; 
    }
    
    return self;
}

- (id)initWithCapacity:(NSUInteger)numItems
{
    self = [self init];
    if (self != nil) {
        [theDict release];
        theDict = [[NSMutableDictionary alloc] initWithCapacity: numItems];
    }
    
    return self;
}

- (id) initWithDictionary:(NSDictionary *)otherDictionary
{
    self = [self init];
    if (self != nil) {
        [theDict release];
        theDict = [[NSMutableDictionary alloc] initWithCapacity:0];
        for (id current in [otherDictionary keyEnumerator]) {
            
          //  NSLog(@"dict deepcopy loop (key:%@), current class:%@",current, [[otherDictionary objectForKey:current] className]);
            
            //we perform a deep copy if found other nsdictionary elements in the dictionary
            if ([[otherDictionary objectForKey:current] respondsToSelector:@selector(objectForKey:)]) {
                
            //    NSLog(@"NSDictionary class!");
                
                CoGeThreadSafeMutableDictionary *temp = [[CoGeThreadSafeMutableDictionary alloc] initWithDictionary:[[[otherDictionary objectForKey:current] mutableCopy] autorelease]];
                [theDict setObject:temp forKey:current];
                [temp release];
                
            } else {
                [theDict setObject:[otherDictionary objectForKey:current] forKey:current];
            }
        }
        
    }
    
    return self;
}


- (NSUInteger)count;
{
    OSSpinLockLock( &spinlock );
    
    NSUInteger _thecount = [theDict count];
    
    OSSpinLockUnlock( &spinlock );

    return _thecount;
}

- (NSEnumerator *) keyEnumerator;
{
    NSEnumerator    *result;
    
    OSSpinLockLock( &spinlock );
    result = [theDict keyEnumerator];
    OSSpinLockUnlock( &spinlock );
    
    return result;
}

- (NSEnumerator *) objectEnumerator;
{
    NSEnumerator    *result;
    
    OSSpinLockLock( &spinlock );
    result = [theDict objectEnumerator];
    OSSpinLockUnlock( &spinlock );
    
    return result;
}


- (id) objectForKey: (id) aKey;
{
    id    result;
    
    OSSpinLockLock( &spinlock );
    result = [theDict objectForKey: aKey];
    [[result retain] autorelease];
    OSSpinLockUnlock( &spinlock );
    
    return result;
}


- (void) removeObjectForKey: (id) aKey;
{
    OSSpinLockLock( &spinlock );
    [theDict removeObjectForKey: aKey];
    OSSpinLockUnlock( &spinlock );
}

-(void)removeAllObjects {

    OSSpinLockLock( &spinlock );
    [theDict removeAllObjects];
    OSSpinLockUnlock( &spinlock );

}


- (void) setObject: (id) anObject forKey: (id) aKey;
{
    [anObject retain];
    
    OSSpinLockLock( &spinlock );
    [theDict setObject: anObject  forKey: aKey];
    OSSpinLockUnlock( &spinlock );
    
    [anObject release];
}

-(NSArray *)allValues {

    id    result;
    
    OSSpinLockLock( &spinlock );
    result = [theDict allValues];
    [[result retain] autorelease];
    OSSpinLockUnlock( &spinlock );
    
    return result;
}

-(NSArray *)allKeys {

    id    result;
    
    OSSpinLockLock( &spinlock );
    result = [theDict allKeys];
    [[result retain] autorelease];
    OSSpinLockUnlock( &spinlock );
    
    return result;

}

- (void) dealloc;
{

    if (!OSSpinLockTry(&spinlock)) {
        OSSpinLockUnlock( &spinlock );
    }
    
 
    [theDict release];
    theDict = nil;
    
    [super dealloc];
}
@end
